Skip to content

[pull] main from fern-api:main#741

Merged
pull[bot] merged 23 commits into
code:mainfrom
fern-api:main
May 19, 2026
Merged

[pull] main from fern-api:main#741
pull[bot] merged 23 commits into
code:mainfrom
fern-api:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 19, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

davidkonigsberg and others added 10 commits May 19, 2026 12:41
…tainers (#15977)

chore(deps): bump moby to v29.5.1 and docker CLI to v29.5.1 in seed containers

Fixes CVE-2026-41567 (GHSA-x86f-5xw2-fm2r), CVE-2026-41568
(GHSA-vp62-88p7-qqf5), and CVE-2026-42306 (GHSA-rg2x-37c3-w2rh)
across dev/python-seed, dev/go-seed, and dev/php-seed containers.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…r-4gwj-5jf2) (#15978)

* chore(security): bump brace-expansion to 5.0.6 in Docker images (GHSA-jxxr-4gwj-5jf2)

Update all generator and seed Dockerfiles to patch npm's bundled
brace-expansion from 5.0.5 to 5.0.6, fixing CVE-2026-45149 /
GHSA-jxxr-4gwj-5jf2 (max option applied too late allows single large
numeric range to allocate ~505 MB).

- 9 Dockerfiles already patching to 5.0.5: bumped to 5.0.6
- 7 Dockerfiles with npm but no brace-expansion patch: added 5.0.6 patch
- 1 Dockerfile using @latest: updated comment GHSA reference

Co-Authored-By: David Konigsberg <davidakonigsberg@gmail.com>

* fix(deps): use npm pack instead of curl for brace-expansion patch in slim images

curl is not available in node:24.15-trixie-slim and node:24.15-alpine
base images. Switch all new brace-expansion patches to use npm pack
(consistent with existing ip-address patches).

Co-Authored-By: David Konigsberg <davidakonigsberg@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: davidkonigsberg <72822263+davidkonigsberg@users.noreply.github.com>
* chore(cli-v2): migrate cache directory to ~/.fern/ for unified Fern directory

Move CLI v2 cache root from XDG-compliant paths (~/.cache/fern/) to ~/.fern/
so all Fern-related files live under a single directory shared with CLI v1.

Changes:
- Default cache root is now ~/.fern/ (was ~/.cache/fern/ on Linux/macOS,
  %LOCALAPPDATA%/fern/cache on Windows)
- Add bin/ cache property for downloaded tool binaries (buf, protoc-gen-openapi),
  naturally shared with CLI v1 at ~/.fern/bin/
- FERN_CACHE_DIR env var and ~/.fernrc overrides still honored
- Update doc comments to reflect new paths

* chore(cli-v2): keep cache root at ~/.cache/fern/, add bin/ for shared binaries

Revert cache root to XDG-compliant ~/.cache/fern/ and add bin/ property
pointing to ~/.fern/bin/ so CLI v2 is aware of CLI v1's existing binary
cache for buf and protoc-gen-openapi.

* chore(cli-v2): move cache root to ~/.fern/ and add bin/ property

Move all CLI v2 cache directories (ir, logs, migrations, bin, tmp) under
~/.fern/ so everything lives in a single directory shared with CLI v1.
FERN_CACHE_DIR env var and ~/.fernrc overrides still honored.

* fix: restore Windows platform-specific cache path handling

Keep %LOCALAPPDATA%/fern/cache for Windows while using ~/.fern/ for
macOS/Linux. Preserves the platform-specific fallback chain.

* chore(cli-v2): keep cache at ~/.cache/fern/, add bin/ redirect to ~/.fern/bin/

Keep CLI v2 cache root at ~/.cache/fern/ (XDG) for ir, logs, migrations.
Add bin/ property that redirects to CLI v1's ~/.fern/bin/ so both CLIs
share the same binary cache for buf and protoc-gen-openapi.

* chore(cli-v2): consolidate cache directory to ~/.fern/

Move CLI v2 cache root from ~/.cache/fern/ to ~/.fern/ for a simpler
migration path. All Fern files (bin, ir, logs, migrations) now live
under a single directory shared with CLI v1.

* chore(cli-v2): restore Windows %LOCALAPPDATA% fallback

Keep platform-specific cache path for Windows (%LOCALAPPDATA%/fern/cache)
while using ~/.fern/ as default on macOS/Linux.

* chore: update changelog to reflect actual PR changes (bin/ property)

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* feat(cli-v2): port `fern docs md` commands from v1

Adds the hidden 'docs md' command group to cli-v2 with two subcommands:

- 'fern docs md generate' (beta): generates MDX documentation from a
  library's source code as described under the 'libraries:' section of
  docs.yml. Reuses the existing '@fern-api/library-docs-generator'
  package for the Python/C++ rendering pipeline and a lightweight
  fetch-based client against the FDR library-docs endpoints.

- 'fern docs md check': validates MDX syntax of pages reachable from the
  docs navigation. Wraps the existing MdxParseValidator and reports
  parse errors with the same source-context formatting as 'docs check'.

The group is marked hidden (description: false) to match the v1
behavior; commandGroup() now accepts 'string | false' to support this.

Closes FER-8920

* chore(cli-v2): apply biome formatting to md commands

* fix(cli): address review feedback on docs md commands port

- Remove dead null-check in CheckCommand: the docsWorkspace == null
  guard was unreachable because workspace.docs != null was already
  checked above and LegacyProjectAdapter always produces docsWorkspaces
  when docs is present
- Add comprehensive test suite for GenerateCommand covering: no docs
  config, no/empty libraries, unknown library flag, unsupported path
  input, happy path (Python + CPP), auth header, FAILED status,
  HTTP start error, --library filtering, and polling timeout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(cli): resolve docs output path relative to docs directory not file

When docs config is referenced via $ref (e.g. $ref: ./fern/docs.yml),
absoluteFilePath points to the .yml file itself. Using it directly as
the base for output path resolution caused ENOTDIR errors because mkdir
was treating the file path as a directory. Fix by taking dirname first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(cli-v2): suppress unhandled rejection warnings in md generate tests

* refactor(cli-v2): address PR review feedback on docs md commands

- commandGroup: take destructured params with optional description instead of string|false
- docs/md/check: remove redundant guard comment
- docs/md/generate: extract shared logic into @fern-api/library-docs-generator orchestrator so v1 and v2 share a single implementation

* style(cli-v2): fix biome lint on docs md generate refactor

* fix(cli): pass LogLevel.Info to TaskContextAdapter in docs md generate

The orchestrator logs success/progress messages via context.logger.info().
TaskContextAdapter defaults to LogLevel.Warn, which silently suppressed
all info-level output (e.g. page counts, success summaries). Pass
LogLevel.Info so users see the generation results.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Merge origin/main into devin/1778522318-cli-v2-port-docs-md-commands

* Adopt destructured commandGroup signature for addLinkCommand after merge

* Fail when specified library not in docs.yml

Add validation to generateLibraryDocs: if a --library value is provided but not present in the parsed docs.yml libraries, the CLI now calls cliContext.failAndThrow with an explanatory message listing available libraries and returns. This surfaces a clear configuration error (CliError.Code.ConfigError) earlier instead of continuing execution.

---------

Co-authored-by: Naman Anand <info@buildwithfern.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ts (#15983)

* fix(generator-cli): restore web-flow signing while keeping fern-bot attribution

`pushSignedCommit` was sending a hardcoded `committer` to
`octokit.git.createCommit` on every API-created commit, which suppressed
GitHub's web-flow signature: the auto-signer only stamps an installation
commit when `committer` is either absent or matches an email verified on
the App's bot user. The hardcoded `115122769+fern-api[bot]@...` matches
the public fern-api App, not the App backing Fiddle's production token,
so cloud-generated PRs have shipped unsigned since 0.9.28.

The signer keys off `committer`, not `author`, so this commit:

- Always sends `author` (defaults to the Fern bot identity) — preserves
  the stable attribution goal from 0.9.28 for every auth flavour,
  including GHE/PAT where the PAT owner would otherwise be the author.
- Sends `committer` only when the caller passes an explicit `author` via
  `PushSignedCommitOptions.author` / `GithubStepConfig.author`. Default
  cloud generations omit `committer`, GitHub fills it in from the App
  installation and signs. Callers that need a deterministic committer
  for downstream tooling can opt in and accept losing the auto-signature.

Tests assert the new shape (`.not.toHaveProperty("committer")` to defend
against vitest's loose object-equality) and cover the explicit-author
path through both the single-attempt and rebase-on-conflict retries.

* chore(generator-cli): tighten signing-fix comments

Per reviewer polish: trim verbose JSDoc/inline blocks, replace the
"verified email on the App's bot user" wording with the more precise
"signing-capable principal (App / OAuth — not PATs)", and shorten the
changelog summary.
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* feat: add commit-and-release mode to GithubSelfhostedMode

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: disable replay for commit-and-release mode (same push-to-base behavior as push mode)

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: handle commit-and-release mode in extractGithubModeFromGenerator for correct telemetry

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(cli): use resolved version for commit-and-release tag when AUTO not used

Plumb the resolved IR-time version into GithubStepConfig.newVersion so
self-hosted commit-and-release mode creates a release/tag even when the
user did not pass --version AUTO. Warn loudly in GithubStep when no
version is available so the silent skip never recurs.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@pull pull Bot locked and limited conversation to collaborators May 19, 2026
@pull pull Bot added the ⤵️ pull label May 19, 2026
github-actions Bot and others added 13 commits May 19, 2026 18:01
* fix(cli): check broken links in folder-referenced pages

The broken link checker was not validating links inside markdown files
referenced via folder entries in docs.yml. Only pages explicitly listed
with page/path entries were checked.

This adds folder expansion to the AST visitor so markdown files within
folder entries are visited and their links validated.

Co-Authored-By: ryanstep <ryanstep@umich.edu>

* fix: sort imports to satisfy biome lint

Co-Authored-By: ryanstep <ryanstep@umich.edu>

* cleanup

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…timeout on large sites (#15981)

fix(cli): use batched requests for link check to prevent timeout on large sites

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: will.kendall@buildwithfern.com <wpk235@gmail.com>
…15986)

* fix(cli): guard streaming-extension parse when only resumable is set

Avoids a TypeError: Cannot read properties of undefined (reading 'startsWith')
when an operation's x-fern-streaming has resumable: true but no format and no
stream-condition. Treats the partial extension as a no-op instead of crashing
the parse.

* chore(seed): pin yarl <1.24 for python-sdk aiohttp install

yarl 1.24.0 and 1.24.1 (published 2026-05-19) ship only cp310 wheels,
which breaks `poetry install --extras aiohttp` on the cp313 python-sdk
test container. Constrain yarl to <1.24 so the test container resolves
to 1.23.0 (which has full wheel coverage). Drop once 1.24.2+ ships.

* Revert "chore(seed): pin yarl <1.24 for python-sdk aiohttp install"

This reverts commit a41a343.
…er `src/` (#15988)

* feat(python): port output_directory flag from Java

Adds `output_directory` (project-root | source-root) to the Python SDK
generator's custom config, mirroring fern-java. source-root mode skips
project scaffolding so the source tree can drop into an existing project.
Composes with package_path; combine with package_name to drop the
`<package>` wrapper entirely. Legacy `flat_layout` preserved as a
deprecated alias.

* chore(python): apply ruff format

* chore(python): type the v2 output_directory check and skip snippet work in source-root

- Introduce OUTPUT_DIRECTORY_OPTIONS / OutputDirectory in SdkCustomConfig so the
  Zod schema and the runtime comparison share the same source of truth.
- Move endpointSnippets generation inside the scaffolding gate; in source-root
  mode the snippets were computed and then discarded.
Co-authored-by: patrickthornton <70873350+patrickthornton@users.noreply.github.com>
Co-authored-by: dsinghvi <10870189+dsinghvi@users.noreply.github.com>
@pull pull Bot merged commit 91981ae into code:main May 19, 2026
1 check failed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants